#include "table.h"
#include "vector.h"
#include "vector3d.h"

#include <iostream>
#include <cmath>
#include <QtOpenGL>

#define THICKNESS 0.3
#define STEP 20
#define STEP2 0.7
#define ERROR -0.001
#define HEIGHT 4.5

Table::Table() : Object(){
    radius = 2.0;
    center = Vector3D(0.0, 0.0, 0.0);
}

Table::Table(double _r, const Vector3D &_c, const Color &_co, unsigned int _id) : Object(_id, _co), radius(_r), center(_c){
}

Table::~Table(){
}

const Vector3D &Table::getCenter() const {
    return center;
}

double Table::intersection (const Vector3D&) const {
    std::cout <<"[TABLE]fazer itersection!!!" <<std::endl;
    return 0;
}

Vector3D Table::getNormalAt (const Vector3D&) const{
    std::cout <<"[TABLE]fazer normal!!!" <<std::endl;
    return Vector3D();
}

void Table::draw(bool _wireframe, bool _showNormal) const {
	glPushMatrix();
	glTranslated(center.x, center.y, center.z);

    if(_wireframe){
        glPolygonMode(GL_FRONT, GL_LINE);
        glPolygonMode(GL_BACK, GL_LINE);
    }


//draw floor
//    glBegin(GL_QUADS);
//        glNormal3f(0.0, 0.0, 1.0);
//
//        glVertex3f(3*radius, 3*radius, -HEIGHT + ERROR);
//        glVertex3f(3*radius, -3*radius, -HEIGHT + ERROR);
//        glVertex3f(-3*radius, -3*radius, -HEIGHT + ERROR);
//        glVertex3f(-3*radius, 3*radius, -HEIGHT + ERROR);
//
//    glEnd();

	drawSurface();
	drawBase();

	glPopMatrix();
}

void Table::drawSurface() const{
	//desenhando o tampo da mesa

	glColor3f(color.r, color.g, color.b);

    glNormal3f(0.0, 0.0, 1.0);
	glBegin(GL_POLYGON);
    for (int i = 0; i <= 360; i += STEP){
        glVertex3f(cos(i*M_PI/180.0)*radius, sin(i*M_PI/180.0)*radius, ERROR);
    }
    glEnd();

    Vector3D v1, v2, v3, vn;
    v1.x = cos(0.0)*radius;
    v1.y = sin(0.0)*radius;
    v1.z = ERROR;
    v2.x = cos(0.0)*radius;
    v2.y = sin(0.0)*radius;
    v2.z = -THICKNESS;
    glBegin(GL_TRIANGLE_STRIP);
    for (int i = STEP; i <= 360; i += STEP){
        for(int j = 0; j < 2; j++){
            v3.x = cos(i*M_PI/180.0)*radius;
            v3.y = sin(i*M_PI/180.0)*radius;
            if(j == 0 /*for par*/){
                v3.z = ERROR;
                vn = ((Vector((v3 - v2).crossProduct(v1 - v2))).normalize()).toVector3D();
            }
            else{
                v3.z = -THICKNESS;
                vn = ((Vector((v1 - v2).crossProduct(v3 - v2))).normalize()).toVector3D();
            }

            glNormal3f(vn.x, vn.y, vn.z);

            glVertex3f(v1.x, v1.y, v1.z);
            glVertex3f(v2.x, v2.y, v2.z);
            glVertex3f(v3.x, v3.y, v3.z);
            v1 = v2;
            v2 = v3;
        }
    }
    glEnd();

    glNormal3f(0.0, 0.0, -1.0);
	glBegin(GL_POLYGON);
    for (int i = 0; i <= 360; i += STEP){
        glVertex3f(cos(i*M_PI/180.0)*radius, sin(i*M_PI/180.0)*radius, -THICKNESS);
    }
    glEnd();
}

void Table::drawBase() const{
	glColor3f(color.r, color.g, color.b);

    double j = 0.0;
    int i;

    Vector3D v1, v2, v3, vn;
    for (j = THICKNESS; j < HEIGHT; j += STEP2) {
        glBegin(GL_TRIANGLE_STRIP);
        v1.x = cos(0.0)*(f(j));
        v1.y = sin(0.0)*(f(j));
        v1.z = -j;

        v2.x = cos(0.0)*(f(j + STEP2));
        v2.y = sin(0.0)*(f(j + STEP2));
        v2.z = -(j + STEP2);

        for (i = STEP; i <= 360; i += STEP){

            v3.x = cos(i*M_PI/180.0)*(f(j));
            v3.y = sin(i*M_PI/180.0)*(f(j));
            v3.z = -j;
            vn = ((Vector((v3 - v2).crossProduct(v1 - v2))).normalize()).toVector3D();

            glNormal3f(vn.x, vn.y, vn.z);

            glVertex3f(v1.x, v1.y, v1.z);
            glVertex3f(v2.x, v2.y, v2.z);
            glVertex3f(v3.x, v3.y, v3.z);
            v1 = v2;
            v2 = v3;

            v3.x = cos(i*M_PI/180.0)*(f(j + STEP2));
            v3.y = sin(i*M_PI/180.0)*(f(j + STEP2));
            v3.z = -(j + STEP2);
            vn = ((Vector((v1 - v2).crossProduct(v3 - v2))).normalize()).toVector3D();

            glNormal3f(vn.x, vn.y, vn.z);

            glVertex3f(v1.x, v1.y, v1.z);
            glVertex3f(v2.x, v2.y, v2.z);
            glVertex3f(v3.x, v3.y, v3.z);
            v1 = v2;
            v2 = v3;
        }
        glEnd();
    }

    glNormal3f(0.0, 0.0, -1.0);
	glBegin(GL_POLYGON);
    for (int i = 0; i <= 360; i += STEP){
        glVertex3f(cos(i*M_PI/180.0)*f(j), sin(i*M_PI/180.0)*f(j), -j);
    }
    glEnd();

}

double Table::f(double d) const{
    double s = 1.0/15.0;
    return ((s*radius * d) * (s*radius * d) * (s*radius * d)) + (1.0/8.0)*radius;
}
